/**
 * Copyright (c) 2013-Now http://jeesite.com All rights reserved.
 */
package com.jeesite.modules.storage.api;

import com.jeesite.common.config.Global;
import com.jeesite.common.lang.StringUtils;
import com.jeesite.modules.storage.common.ServerResponse;
import com.jeesite.modules.storage.entity.Order;
import com.jeesite.modules.storage.service.MemberService;
import com.jeesite.modules.storage.service.OrderService;
import com.jeesite.modules.storage.util.WeChatUtil;
import com.jeesite.modules.storage.util.WebUtil;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.util.Map;
import java.util.SortedMap;

/**
 * 微信Controller
 */
@RestController(value = "apiwechat")
@RequestMapping(value = "/api/wechat")
public class WechatController extends APIController {

    @Autowired
    private MemberService memberService;

    @Autowired
    private OrderService orderService;

    /**
     * 微信登录
     * @param platform 平台【APP或H5】
     * @param unionId 微信UnionId
     * @param openId 微信OpenId
     * @param avatar 微信头像
     * @param nickName 微信昵称
     * @return 登录结果
     * 200 成功登陆
     * 500 其它
     * 501 未绑定手机号
     */
    @RequestMapping(method = RequestMethod.POST,value = "login")
    public ServerResponse<String> login(@RequestParam(value="platform") String platform, @RequestParam(value="unionId") String unionId, @RequestParam(value="openId") String openId, @RequestParam(value="avatar") String avatar, @RequestParam(value="nickName") String nickName)
    {
        /**
         * 微信登录
         * 500 其它
         * 501 未注册
         */
        switch (this.memberService.loginWechat(platform,unionId , openId,avatar,nickName)){
            case 200:
            {
                return ServerResponse.createBySuccess(200,"成功登陆",memberService.getIdByPhoneOrOpenId(platform,null, openId));
            }
            case 501:
            {
                return  ServerResponse.createBySuccess(501,"未绑定手机号");
            }
            default:
            {
                return ServerResponse.createBySuccess(500,"其它");
            }
        }
    }

    /**
     * 微信绑定
     * @param platform 平台【APP或H5】
     * @param memberId 会员id
     * @param unionId 微信UnionId
     * @param openId 微信OpenId
     * @param avatar 微信头像
     * @param nickName 微信昵称
     * @return 绑定结果
     * 200 成功绑定
     * 500 其它
     * 501 会员id不能为空
     * 502 会员不存在
     * 503 已绑定该微信号，无需重复绑定
     * 504 该微信已绑定其它账号
     */
    @RequestMapping(method = RequestMethod.POST,value = "bind")
    public ServerResponse<Boolean> bind(@RequestParam(value="platform") String platform,@RequestParam(value="memberId") String memberId, @RequestParam(value="unionId") String unionId, @RequestParam(value="openId") String openId, @RequestParam(value="avatar") String avatar, @RequestParam(value="nickName") String nickName )
    {
        /**
         * 微信绑定
         * 500 其它
         * 501 会员id不能为空
         * 502 会员不存在
         * 503 该微信已绑定其它账号
         */
        switch (this.memberService.bindWechat(platform,memberId, unionId , openId,avatar,nickName)){
            case 200:
            {
                return ServerResponse.createBySuccess(200,"成功绑定",true);
            }
            case 501:
            {
                return ServerResponse.createBySuccess(501,"会员id不能为空",false);
            }
            case 502:
            {
                return ServerResponse.createBySuccess(502,"会员不存在",false);
            }
            case 503:
            {
                return  ServerResponse.createBySuccess(504,"该微信已绑定其它账号",false);
            }
            default:
            {
                return ServerResponse.createBySuccess(500,"其它",false);
            }
        }
    }

    /**
     * 解绑微信
     * @param memberId 会员id
     * @return 解绑结果
     * 200 成功解绑
     * 500 其它
     * 501 会员id不能为空
     * 502 会员不存在
     */
    @RequestMapping(method = RequestMethod.POST,value = "unbind")
    public ServerResponse<Boolean> unbind(@RequestParam(value="memberId") String memberId)
    {
        /**
         * 解绑微信
         * 500 其它
         * 501 会员Id不能为空
         * 502 会员不存在
         */
        switch (this.memberService.unbindWechat(memberId)){
            case 200:
            {
                return ServerResponse.createBySuccess(200,"成功解绑",true);
            }
            case 501:
            {
                return ServerResponse.createBySuccess(501,"会员Id不能为空",false);
            }
            case 502:
            {
                return ServerResponse.createBySuccess(502,"会员不存在",false);
            }
            default:
            {
                return ServerResponse.createBySuccess(500,"其它",false);
            }
        }
    }

    /**
     * app支付
     * @param orderId 订单Id
     * @return
     */
    @RequestMapping(method = RequestMethod.POST,value = "pay/app")
    public ServerResponse<Object> appPay(@RequestParam(value="platform") String platform,@RequestParam(value="orderId") String orderId) throws Exception {
        return ServerResponse.createBySuccess(200, orderService.doPay(orderId,platform,"Wechat",null));
    }

    /**
     * 构造openId连接
     * @return
     */
    @RequestMapping(method = RequestMethod.GET,value = "authorize")
    public void authorize(@RequestParam(value="redirectUri") String redirectUri, HttpServletResponse response) throws IOException {
        String url = Global.getConfig("storage.url.h5") + redirectUri;
        url = WeChatUtil.buildAuthorizeUrl(java.net.URLEncoder.encode(url,"utf-8"),"snsapi_base");
        response.sendRedirect(url);
    }

    /**
     * 获取openId
     * @return
     */
    @RequestMapping(method = RequestMethod.GET,value = "openid")
    public void openId(@RequestParam(value="code",required = false) String code, @RequestParam(value="redirectUri",required = false) String redirectUri, HttpServletResponse response) throws IOException {
        redirectUri = Global.getConfig("storage.url.h5") + redirectUri;
        redirectUri += (redirectUri.contains("?") ? "&" : "?") + "openId="+WeChatUtil.getOpenIdByCode(code);
        response.sendRedirect(redirectUri);
    }

    /**
     * H5支付
     * @param orderId 订单Id
     * @return
     */
    @RequestMapping(method = RequestMethod.POST,value = "pay/h5")
    public ServerResponse<Object> h5Pay(@RequestParam(value="platform") String platform,@RequestParam(value="openId") String openId,@RequestParam(value="orderId") String orderId) throws Exception {
        return ServerResponse.createBySuccess(200, orderService.doPay(orderId,platform,"Wechat",openId));
    }

    /**
     * 异步同步
     * <xml><appid><![CDATA[wxc103353db679748a]]></appid>
     * <bank_type><![CDATA[PAB_CREDIT]]></bank_type>
     * <cash_fee><![CDATA[1]]></cash_fee>
     * <fee_type><![CDATA[CNY]]></fee_type>
     * <is_subscribe><![CDATA[N]]></is_subscribe>
     * <mch_id><![CDATA[1523251831]]></mch_id>
     * <nonce_str><![CDATA[miNyTeJ8exxCYH8n]]></nonce_str>
     * <openid><![CDATA[oGmTM5iVP2asPc9E6jWPTsWPHIdE]]></openid>
     * <out_trade_no><![CDATA[b7c7888755dc4842aa621f88c71239df]]></out_trade_no>
     * <result_code><![CDATA[SUCCESS]]></result_code>
     * <return_code><![CDATA[SUCCESS]]></return_code>
     * <sign><![CDATA[9B22B648598D52C5F7A30CCF35368E07]]></sign>
     * <time_end><![CDATA[20200205143114]]></time_end>
     * <total_fee>1</total_fee>
     * <trade_type><![CDATA[APP]]></trade_type>
     * <transaction_id><![CDATA[4200000488202002057271851124]]></transaction_id>
     * </xml>
     * @return
     */
    @RequestMapping(method = RequestMethod.POST,value = "notify")
    public String notify(HttpServletRequest request) throws Exception {
        InputStream inputStream = request.getInputStream();
        BufferedReader reader = new BufferedReader(new InputStreamReader(inputStream));
        StringBuilder stringBuilder = new StringBuilder();
        String line;
        while ((line = reader.readLine()) != null) {
            stringBuilder.append(line + "\n");
        }
        String result = stringBuilder.toString();
        Map<String, String> map = WeChatUtil.xmlToMap(result);
        if(!(map.containsKey("result_code") && String.valueOf(map.get("result_code")).equals("SUCCESS")&&map.containsKey("return_code") && String.valueOf(map.get("return_code")).equals("SUCCESS"))){
            return "";
        }
        String outTradeNo = map.containsKey("out_trade_no") ? String.valueOf(map.get("out_trade_no")) : "";
        if(StringUtils.isBlank(outTradeNo)){
            return "";
        }
        String transactionId = map.containsKey("transaction_id") ? String.valueOf(map.get("transaction_id")) : "";
        if(StringUtils.isBlank(transactionId)){
            return "";
        }
        //支付回调
        if(outTradeNo.startsWith("pay") && orderService.payHandle(WebUtil.getOrderIdByTradeNo(outTradeNo),transactionId) == 200){
            return "<xml><return_code><![CDATA[SUCCESS]]></return_code><return_msg><![CDATA[OK]]></return_msg></xml>";
        }
        return "";
    }
}
